import os
import traceback
from urllib import parse

import requests
from urllib3.exceptions import InsecureRequestWarning

from src.configread import MyConfigParser

printfunc = lambda LogBool, string: print(string) if LogBool else print("")

# 关闭r对象
closeResult = lambda r: r.close() if 'r' in locals() and r else None
r = ''

abspath = os.path.dirname(os.path.abspath(__file__))
configpath = os.path.join(abspath, "db.ini")
configdicts = MyConfigParser().get_conf_dict_file(configpath)


def urlQuery2List(url):
    return parse.parse_qs(parse.urlparse(url).query)

def single_read_file(filePath, encoding="utf-8", num=-1):
    """
    读取文件中的所有值
    :param filePath:
    :param encoding:
    :param num  读取指定长度 可以用于解决无换行大文件问题 默认-1读取全部
    :return:
    """
    with open(filePath, encoding=encoding) as f:
        return f.read(num)

def single_write_file(value, files, encoding="utf-8"):
    """
    单次将内容写入文件
    写入值到文件 每次写入会覆盖原来的文件  文件不存在会自动创建
    :param value:
    :param files:
    :return:
    """
    with open(files, 'w', encoding=encoding) as f:
        f.write(value)


def create_dir(pathdir):
    if not os.path.exists(pathdir):
        os.makedirs(pathdir)


def get_dir_all_files(path):
    # 遍历子目录
    assert os.path.isdir(path), NotADirectoryError(path + " not is a dir please check")
    for path, dirNames, fileNames in os.walk(path, topdown=True):
        # 获取当前目录的所有文件
        for fileName in fileNames:
            yield os.path.join(path, fileName)


def BaseRequest(url, sn=None, LogBool=True, endstring="</html>", mark="", **kwargs):
    """
    网络请求的基本结构
    :param url:  请求的url
    :param sn:  会话  sn = requests.Session() 这样保存会话
    :param LogBool: 是否打印一些显示
    :param endstring:  判断html的结束字符串 一般html默认 </html> 结尾
    :param mark:  标志符 默认为""  你的结果中的一些字符串或特殊的标签都可以
    :param kwargs: requests请求的一些参数
    :return: true表示成功 false表示失败或需要进行检查的数据，同时返回r
    BoolResult, errString, r
    """
    r = None
    exMsg = None
    try:
        requests.urllib3.disable_warnings(InsecureRequestWarning)
        printfunc(LogBool, url)
        if sn:
            r = sn.get(url=url, **kwargs)
        else:
            r = requests.get(url=url, **kwargs)
    except:
        exMsg = '* ' + traceback.format_exc()
        printfunc(LogBool, exMsg)
    finally:
        closeResult(r)

    if exMsg:
        print("判断到except，请求出项错误")
        return False, "request", r

    if r.status_code != 200:
        print('error url:' + r.url)
        print('r.status_code:' + str(r.status_code))
        return False, "code", r

    if endstring:
        """
        请求有可能是html或者json等，如果有需要判断html结束的才启动这个选项
        """
        html = r.text.strip()
        if not html.endswith(endstring):
            print("not endswith {}".format(endstring))
            return False, "endString", r

    if mark:
        """
       验证请求是否成功  通过一个特征字符串或者html的标签来查找 保证下载的页面是我需要的页面
       而不是错误页面
       特征值有可能没有是网页出现问题  有可能是请求不完全 这个依照情况而定
        """
        html = r.text.strip()
        if html.find(mark) == -1:
            print('not found {}'.format(mark))
            return False, "Feature err", r
        else:
            print("found mark is {}".format(mark))

    return True, "", r


def BaseRequestPost(url, sn=None, data=None, LogBool=True, endstring="</html>", mark="", **kwargs):
    """
    网络请求的基本结构
    :param url:  请求的url
    :param sn:  会话  sn = requests.Session() 这样保存会话
    :param LogBool: 是否打印一些显示
    :param endstring:  判断html的结束字符串 一般html默认 </html> 结尾
    :param mark:  标志符 默认为""  你的结果中的一些字符串或特殊的标签都可以
    :param kwargs: requests请求的一些参数
    :return: true表示成功 false表示失败或需要进行检查的数据，同时返回r
    """
    r = None
    exMsg = None
    try:
        printfunc(LogBool, url)
        if sn:
            print("使用 sn请求")
            r = sn.post(url=url, data=data, **kwargs)
        else:
            print("使用 requets请求")
            requests.urllib3.disable_warnings(InsecureRequestWarning)
            r = requests.post(url=url, data=data, **kwargs)
    except:
        exMsg = '* ' + traceback.format_exc()
        printfunc(LogBool, exMsg)
    finally:
        closeResult(r)

    if exMsg:
        print("判断到except，请求出项错误")
        return False, "request", r

    if r.status_code != 200:
        print('error url:' + r.url)
        print('r.status_code:' + str(r.status_code))
        return False, "code", r

    if endstring:
        """
        请求有可能是html或者json等，如果有需要判断html结束的才启动这个选项
        """
        html = r.text.strip()
        if not html.endswith(endstring):
            print("not endswith {}".format(endstring))
            return False, "endString", r

    if mark:
        """
       验证请求是否成功  通过一个特征字符串或者html的标签来查找 保证下载的页面是我需要的页面
       而不是错误页面
       特征值有可能没有是网页出现问题  有可能是请求不完全 这个依照情况而定
        """
        html = r.text.strip()
        if html.find(mark) == -1:
            print('not found {}'.format(mark))
            return False, "Feature err", r

    return True, "", r
